import 'dart:async';
import 'dart:math';
import 'dart:ui';

class GameSetting {
  GameSetting._();

  static final GameSetting _default = GameSetting._();

  factory GameSetting() => _default;

  ///游戏难度 8*8
  int difficult = 8;

  ///雷的数量 (格子总数 * 0.18 向下取整)，通常扫雷的雷数在0.16-0.2之间。
  int get mines => (difficult * difficult * 0.18).floor();

  ///默认主题
  Color themeColor = const Color(0xFF5ADFD0);

  late List<List<int>> board; //棋盘
  late List<List<bool>> revealed; // 记录格子是否被翻开
  late List<List<bool>> flagged; //记录格子是否被标记
  late bool gameOver; //游戏是否结束
  late bool win; //是否获胜
  late int numRows; // 行数
  late int numColumns; // 列数
  late int numMines; // 雷数
  late int numFlags;

  //游戏时间
  late int _playTime;
  late Timer timer;

  void init() {
    numRows = difficult;
    numColumns = difficult;
    numMines = mines;
    // 初始化棋盘
    board = List.generate(numRows, (index) => List.filled(numColumns, 0));
    // 初始化格子是否被翻开
    revealed =
        List.generate(numRows, (index) => List.filled(numColumns, false));
    // 初始化格子是否被标记
    flagged = List.generate(numRows, (_) => List.filled(numColumns, false));
    // 将游戏定义为未结束
    gameOver = false;
    // 将游戏定义为还未获胜
    win = false;
    numFlags = mines;
    _layMines();
    _playTime = 0;
  }

  //布置地雷
  void _layMines() {
    int numMinesPlaced = 0;
    while (numMinesPlaced < numMines) {
      int i = Random().nextInt(numRows);
      int j = Random().nextInt(numColumns);
      if (board[i][j] != -1) {
        board[i][j] = -1;
        numMinesPlaced++;
      }
    }
    for (int i = 0; i < numRows; i++) {
      for (int j = 0; j < numColumns; j++) {
        if (board[i][j] != -1) {
          int count = 0;
          for (int i2 = max(0, i - 1); i2 <= min(numRows - 1, i + 1); i2++) {
            for (int j2 = max(0, j - 1);
                j2 <= min(numColumns - 1, j + 1);
                j2++) {
              if (board[i2][j2] == -1) {
                count++;
              }
            }
          }
          board[i][j] = count;
        }
      }
    }
  }

  void reveal(int i, int j) {
    revealed[i][j] = true;
    //如果翻开的是地雷
    if (board[i][j] == -1) {
      //将所有的地雷翻开,告诉用户所有的地雷位置
      for (int i2 = 0; i2 < numRows; i2++) {
        for (int j2 = 0; j2 < numColumns; j2++) {
          if (board[i2][j2] == -1) {
            revealed[i2][j2] = true;
          }
        }
      }
      //游戏结束
      gameOver = true;
      //结束动画
    }
    //如果点击的格子周围都没有雷就自动翻开相邻的空格
    if (board[i][j] == 0) {
      for (int i2 = max(0, i - 1); i2 <= min(numRows - 1, i + 1); i2++) {
        for (int j2 = max(0, j - 1); j2 <= min(numColumns - 1, j + 1); j2++) {
          if (!revealed[i2][j2]) {
            reveal(i2, j2);
          }
        }
      }
    }
  }

  ///它会遍历整个棋盘，检查每一个未被翻开的格子是否都是地雷，
  bool checkWin() {
    for (int i = 0; i < numRows; i++) {
      for (int j = 0; j < numColumns; j++) {
        if (board[i][j] != -1 && !revealed[i][j]) {
          return false;
        }
      }
    }
    return true;
  }

  String get playTime {
    int minutes = (_playTime ~/ 60); // 计算分钟数
    int seconds = (_playTime % 60); // 计算秒数
    //padLeft方法用于补齐不足两位的数字，第一个参数是补齐后的字符串总长度，第二个参数是用于补齐的字符。
    return '${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';
  }
  set incrementPlayTime(int value){
    _playTime+=value;
  }
}

enum BlockType {
  //数字
  figure,
  //雷
  mine,
  //标记
  label,
  //未标记（未被翻开）
  unlabeled,
}
